package tp.pr5.mv;

import tp.pr5.mv.instructions.arithmetic.*;
import tp.pr5.mv.instructions.io.*;
import tp.pr5.mv.instructions.jump.*;
import tp.pr5.mv.instructions.logic.*;
import tp.pr5.mv.instructions.mem.*;
import tp.pr5.mv.instructions.stack.*;
import tp.pr5.mv.instructions.system.*;


public class InstructionParser {

	
	private static Instruction Set[] = { new ADD(), new DIV(), new DUP(), new FLIP(), new HALT(), new LOAD(), new MUL(), new OUT(), 
		new POP(), new PUSH(), new STORE(), new SUB(), new AND(), new OR(), new NOT(), new LT(), new GT(), new EQ(), 
		new LE(), new BE(), new NEG(), new JUMP(), new BT(), new BF(), new RJUMP(), new RBT(), new RBF(), new JUMPIND(), new LOADIND(), new STOREIND(), new In()	};
	
	
	public static Instruction parse( String line ) {
		
		Instruction instrNull = null;
		
		line = line.toUpperCase();      // Pasamos la línea a mayúsculas.
		
		line = line.trim();  // Tratamiento de los blancos en la cadena.
		String[] words = line.split(" +");
		
		int numWords = words.length;   
		
		
		if ( numWords == 1 )       // Si sólo se ha introducido una palabra...
		
			for ( Instruction inst :  Set )  // Vamos comparando nuestra instrucción con aquellas del array de instrucciones para ver con cuál de ellas coincide.
			{
				Instruction ret = inst.parse(words[0], "" );   // Incluimos la cadena vacía como segundo parámetro.
				
				if ( ret != null )
					return ret;
			} 
		
		
		else if ( numWords >= 2 )   // Si se han introducido dos o más palabras...
		
			for ( Instruction inst :  Set )
			{
				Instruction ret = inst.parse(words[0], words[1]);
				
				if ( ret != null )
					return ret;
			}
			
		return instrNull;   // Si ha salido de alguno de los for significa que no es una instrucción válida.
		
	}
	
	
}
